#include "uploadthreadlist.h"



void uploadThreadList::append(ImageToUpload image, QHttp* httpHandler,
			int httpPostId, bool finished)
{
	append(image, httpHandler, finished);
	setHttpPostId(httpHandler, httpPostId);
}

void uploadThreadList::append(ImageToUpload image, QHttp* httpHandler, bool finished)
{
	qDebug() << "append image:" << image.ImageName << image.index;
	uploadThread* thread = append(httpHandler);
	UploadResult links;
	links.index = image.index;
	links.size = image.size;
	links.ImageName = image.ImageName;
	links.success = false;
	qDebug() << "images count" << thread->imagesAndResults.count();
	thread->imagesAndResults.append(QPair<ImageToUpload, UploadResult>(image, links));
//	thread->uploadedLinks.append(links);
//	thread->images.append(image);
	thread->finished = finished;
}

void uploadThreadList::append(QList<ImageToUpload> images, QHttp* httpHandler, int httpPostId, bool finished) {
	append(images, httpHandler, finished);
	setHttpPostId(httpHandler, httpPostId);
}

void uploadThreadList::append(QList<ImageToUpload> images, QHttp* httpHandler, bool finished)
{
	uploadThread* thread = append(httpHandler);
	foreach(ImageToUpload image, images) {
		UploadResult links;
		links.index = image.index;
		links.size = image.size;
		links.ImageName = image.ImageName;
		links.success = false;
		thread->imagesAndResults.append(QPair<ImageToUpload, UploadResult>(image, links));
//		thread->uploadedLinks.append(links);
	}
//	thread->images.append(images);
	thread->finished = finished;
}

uploadThreadList::uploadThread* uploadThreadList::append(QHttp* httpHandler)
{
	uploadThread* thread;
	if ( httpMap.contains(httpHandler) ) {
		thread = httpMap[httpHandler];
	} else {
		thread = new uploadThread();
		thread->httpHandler = httpHandler;
		thread->resultPage = httpHandler->currentDestinationDevice();
		httpMap.insert(httpHandler, thread);
	}
	return thread;
}

void uploadThreadList::setHttpPostId(const QHttp* httpHandler, int httpPostId) {
	findThread(httpHandler)->httpPostId = httpPostId;
}

void uploadThreadList::appendBroken(ImageToUpload image, QString error)
{
	UploadResult result;
	result.success = false;
	result.errorString = error;
	result.ImageName = image.ImageName;
	result.index = image.index;
	result.size = image.size;
	broken.append(QPair<ImageToUpload, UploadResult>(image, result));
}

uploadThreadList::uploadThread* uploadThreadList::findThread(const QHttp* httpHandler)
{
	Q_ASSERT(httpHandler);
	uploadThread* thr = httpMap[httpHandler];
	Q_ASSERT(thr);
	return thr;
}

QHttp::Error uploadThreadList::errorReason(const QHttp* httpHandler) {
	return httpHandler->error(); // LOL :-D I think, I should remove this function in nearest future )))
}

void uploadThreadList::setFinished(const QHttp* httpHandler, const bool &finished) {
	findThread(httpHandler)->finished = finished;
}

void uploadThreadList::finishThread(const QHttp* httpHandler) {
	uploadThread *thread = this->findThread(httpHandler);
	thread->resultPage->deleteLater();
	thread->finished = true;
}

bool uploadThreadList::isFinished(const QHttp* httpHandler) {
	return findThread(httpHandler)->finished;
}

bool uploadThreadList::success(const QHttp* httpHandler) {
	foreach(UploadResult links, uploadedLinks(httpHandler)) {
		if (!links.success)
			return false;
	}
	return true;
}

int uploadThreadList::postId(const QHttp* httpHandler) {
	return findThread(httpHandler)->httpPostId;
}

QList<UploadResult> uploadThreadList::uploadedLinks(const QHttp* httpHandler) {
	QList<UploadResult> links;
	QPair<ImageToUpload, UploadResult> pair;
	foreach (pair, findThread(httpHandler)->imagesAndResults)
		links.append(pair.second);
	return links;
}

QList<ImageToUpload> uploadThreadList::images(const QHttp* httpHandler) {
	QList<ImageToUpload> images;
	QPair<ImageToUpload, UploadResult> pair;
	foreach (pair, findThread(httpHandler)->imagesAndResults)
		images.append(pair.first);
	return images;
}

UploadResult uploadThreadList::uploadedLinks(const QHttp* httpHandler, int imageIndex) {
	QList<QPair<ImageToUpload, UploadResult> > &list = findThread(httpHandler)->imagesAndResults;
	QPair<ImageToUpload, UploadResult> pair;
	foreach(pair, list) {
		if (pair.second.index == imageIndex)
			return pair.second;
	}
	Q_ASSERT(false); // I don't even guess what to do in such a case. May be I should turn to Exceptions?
	return list.at(-1).second; // to avoid compiler warnings only
}

QIODevice* uploadThreadList::resultPage(const QHttp* httpHandler) {
	return findThread(httpHandler)->resultPage;
}

void uploadThreadList::setResultPage(const QHttp* httpHandler, QIODevice* resultPage) {
	findThread(httpHandler)->resultPage = resultPage;
}

bool uploadThreadList::findResult(uploadThread* thread, const UploadResult &uploadRes, int &index) {
	for(int i = 0; i < thread->imagesAndResults.count(); i++) {
		if ( uploadRes.index == thread->imagesAndResults[i].second.index ) {
			index = i;
			return true;
		}
	}
	return false;
}
/*
void uploadThreadList::setUploadResult(const QHttp* httpHandler, UploadResult &uploadResult) {
	int index = -1;
	if ( findResult(findThread(httpHandler), uploadResult, index) )
		httpMap[httpHandler]->uploadedLinks.replace(index, uploadResult);
	else
		httpMap[httpHandler]->uploadedLinks.append(uploadResult);
}
*/
void uploadThreadList::mergeUploadResult(const QHttp* httpHandler, const QList<UploadResult> &uploadResult) {
	for(int i = 0; i < uploadResult.count(); i++)
		mergeUploadResult(httpHandler, uploadResult.at(i), i);
}

void uploadThreadList::mergeUploadResult(const QHttp* httpHandler, const UploadResult &uploadResult, int postIndex) {
	UploadResult &tmp = findThread(httpHandler)->imagesAndResults[postIndex].second;
	if (uploadResult.ImageName != tmp.ImageName) {
		qWarning() << "Achtung! Image name does not match! Original image name:" << tmp.ImageName << "result image name:" << uploadResult.ImageName;
	}
	tmp.errorString = uploadResult.errorString;
	tmp.success = uploadResult.success;
	qDebug() << "from merge result (base plugin) success:" << tmp.index << tmp.success;
	tmp.Image = uploadResult.Image;
	tmp.ImageHtml = uploadResult.ImageHtml;
	tmp.Thumb = uploadResult.Thumb;
	tmp.CommonHtml = uploadResult.CommonHtml;
	tmp.SessionHtml = uploadResult.SessionHtml;
}

QList<int> uploadThreadList::imageIndex(const QHttp* httpHandler) {
	QList<int> ret;
	foreach(UploadResult img, this->uploadedLinks(httpHandler) )
		ret << img.index;
	return ret;
}

void uploadThreadList::setErrorString(const QHttp* httpHandler, const QString &errorStr, const bool error) {
	findThread(httpHandler)->errorString = errorStr;
	foreach(UploadResult img, this->uploadedLinks(httpHandler) ) {
		if ( img.errorString.isEmpty() )
			img.errorString = errorStr;
		img.success = !error;
		this->mergeUploadResult(httpHandler, img, img.index);
	}
}

QString uploadThreadList::errorString(const QHttp* httpHandler) {
	return findThread(httpHandler)->errorString;
}

QString uploadThreadList::errorString(const QHttp* httpHandler, int imageIndex) {
	foreach(UploadResult res, this->uploadedLinks(httpHandler) ) {
		qDebug() << res.index << res.success << res.errorString;
		if (res.index == imageIndex && res.success == false)
			return res.errorString;
	}
	return QString::null;
}

int uploadThreadList::countRunning()
{
	int res = 0;
	foreach (uploadThread* thread, httpMap) {
		if (!thread->finished)
			res++;
	}
	qDebug() << "Count running:" << res;
	return res;
}

void uploadThreadList::abortAllRunning()
{
	foreach (uploadThread* thread, httpMap) {
		if (!thread->finished) {
			setErrorString(thread->httpHandler, "Cancelled by user");
			thread->httpHandler->abort();
		}
	}
}

QList<UploadResult> uploadThreadList::linksList()
{
	QList<UploadResult> list;
	QPair<ImageToUpload, UploadResult> pair;
	foreach (uploadThread* thread, httpMap) {
		if (thread->finished) {
			foreach(pair, thread->imagesAndResults)
				list << pair.second;
		}
	}
	foreach (pair, broken)
		list.append(pair.second);
	qDebug() << "List contains links:" << list.count();
	return list;
}

void uploadThreadList::truncate()
{
	foreach (uploadThread* thread, httpMap)
		thread->httpHandler->deleteLater();
	httpMap.clear();
}

